package com.bfxy.disruptor.heigh.chain;

import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 感觉这个部分的东西，好像那个activityflow的框架哦，流程的那个
 * 实际这是个fock join的操作
 */
@SuppressWarnings("all")
public class Main {


    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {

        //构建一个线程池用于提交任务
        // 这个线程池是用于提交整个任务的
        ExecutorService es1 = Executors.newFixedThreadPool(1);
        // 用于构建disruptor框架的参数,这里有个坑，这里设置的线程数量有鬼，有几个监听者,
        // 那么应该就有几个线程，那么是动态的该如何解决呢，如果是多消费者就了，就不会有这个问题
        ExecutorService es2 = Executors.newFixedThreadPool(5);
        //1 构建Disruptor
        Disruptor<Trade> disruptor = new Disruptor<Trade>(
                new EventFactory<Trade>() {
                    @Override
                    public Trade newInstance() {
                        return new Trade();
                    }
                },
                1024 * 1024,
                es2,
                ProducerType.SINGLE,
                new BusySpinWaitStrategy());


        //2 把消费者设置到Disruptor中 handleEventsWith

        //2.1 串行操作：
//         disruptor
//         .handleEventsWith(new Handler1())
//         .handleEventsWith(new Handler2())
//         .handleEventsWith(new Handler3())
//         .handleEventsWith(new Handler4())
//                 .handleEventsWith(new Handler5());


        //2.2 并行操作: 可以有两种方式去进行
        //1 handleEventsWith方法 添加多个handler实现即可
        //2 handleEventsWith方法 分别进行调用

//         disruptor.handleEventsWith(new Handler1(), new Handler2(), new Handler3());
//         disruptor.handleEventsWith(new Handler2());
//         disruptor.handleEventsWith(new Handler3());


        //2.3 菱形操作 (一)

         /*disruptor.handleEventsWith(new Handler1(), new Handler2())
         .handleEventsWith(new Handler3());*/

        //2.3 菱形操作 (二)

//         EventHandlerGroup<Trade> ehGroup = disruptor.handleEventsWith(new Handler1(), new Handler2());
//         ehGroup.then(new Handler3());

        //2.4 六边形操作
//        Handler1 h1 = new Handler1();
//        Handler2 h2 = new Handler2();
//        Handler3 h3 = new Handler3();
//        Handler4 h4 = new Handler4();
//        Handler5 h5 = new Handler5();
//        disruptor.handleEventsWith(h1, h4);
//        disruptor.after(h1).handleEventsWith(h2);
//        disruptor.after(h4).handleEventsWith(h5);
//        disruptor.after(h2, h5).handleEventsWith(h3);


        //3 启动disruptor
        RingBuffer<Trade> ringBuffer = disruptor.start();

        CountDownLatch latch = new CountDownLatch(1);

        long begin = System.currentTimeMillis();

        es1.submit(new TradePushlisher(latch, disruptor));


        latch.await();    //进行向下

        disruptor.shutdown();
        es1.shutdown();
        es2.shutdown();
        System.err.println("总耗时: " + (System.currentTimeMillis() - begin));


    }
}
